/* $.touch plugin
 * copyright 2009 Clark Van Oyen
 * This software contained in this file is dual-licensed, under either the GPL or MIT license.
 * This is the same licensing as the jQuery library.
 */

/*
 * usage:
 * $.touch(CSS_SELECTORS) creates dom elements matching the provided CSS_SELECTORS, which is any number of string arguments.
 * $().touch(CSS_SELECTORS) is (almost) equivalent to $().append($.touch(CSS_SELECTOR))
 */
 
(function($){ /* Touch Selector plugin */
  var SH;
  
  $.touch = function() {
    var arg_tree,sel,$elem,$out = $([]);
    
    $.each(arguments,function(i,arg) {
    
      if (typeof arg === 'string') {
      
        // see if the element has child elements.
        arg_tree = arg.match(/^([^\s>]+?)(>|\s\s)(.*)$/);
        // if there are, render only the parent first.
        if (arg_tree) {
          arg = arg_tree[1];
        }
        
        // get id, class, attribute selectors
        sel = arg.match(/(^[^\.#\[]+)(#[^\.#]+|)(\.[a-zA-Z\d\-_]+|)(\[[^=]+=["'][^\]"']+["']\]|)$/);
        if (!sel) {
          console.log('Touch Selector: Invalid Selector "'+arg+"'");
        }
        
        // apply id, class, attribute properties.
        $elem = $(document.createElement(SH.DEFS[sel[1]] || sel[1]));
        if (sel.length > 2 && sel[2]) {
          $elem.attr('id',sel[2].substring(1));
        }
        if (sel.length > 3 && sel[3]) {
          $elem.addClass(sel[3].substring(1));
        }
        if (sel.length > 4 && sel[4]) {
          pair = sel[4].match(/\[([^=]+)=["']([^\]"']+)["']\]/);
          $elem.attr(pair[1],pair[2]);
        }
        
        // apply shortcut pseudo-elements
        if (SH.ATTR[sel[1]]) {
          $elem.attr(SH.ATTR[sel[1]]);
        }
        
        // if implied child elements existed in selector, render them inside this element.
        if (arg_tree) {
          if (arg_tree[2] == '>') {
            $elem.touch(arg_tree[3]);
          } else {
            $elem.html(arg_tree[3]);
          }
        }
        
      } else {
        $elem = $(arg);
      }

      $out = $out.add($elem);
    });

    return $out;
  };
  
  $.extend($.touch, {
  /*a set of utlities for manipulating the dom based on selectors.
   */
      SHORTHAND: {
        DEFS: { // shorthand selector map
          txt:'input',
          btn:'input',
          hid:'input',
          pwd:'input'
        },
        ATTR: { // attributes for shorthand selectors
          txt:{type:'text'},
          btn:{type:'button'},
          hid:{type:'hidden'},
          pwd:{type:'password'}
        }
      },
      img: function(src,alt) {
        return $.touch('img').attr({
            src:src,
            alt:alt || src.match(/\/([^\/]*?)\.[^\.]+$/)[1]
          });
      },
      link: function(link,text) {
        return $.touch('a').append(text).attr('href',link);
      },
      /* macro factory 
       * ie) $DIV = $.touch.generate_macro('div');
       */
      generate_macro: function(str) {
      	return function() {
      		$.touch(str).touch(arguments);
      	}
      }
  });
  SH = $.touch.SHORTHAND;
  $.fn.touch = function() {
    tgt = this;
    $.each(arguments,function(i,selector) {
        if (typeof selector == 'string' && selector.substring(0,1)==' ') tgt.append(selector.substring(1));
        else {
          tgt.append( $.touch( selector ) );
        }
    });
    return this;
  };
  /* end Touch Selector plugin */
})(jQuery);


